var request = require("request");
var express = require('express');
var mongoclient = require('mongodb').MongoClient
var Iconv  = require('iconv').Iconv;
var jsdom = require('jsdom');
var app = express();

var mongodb;
var urls = {
    base: "http://cinemacity.bg/",
    cinemas: "http://cinemacity.bg/program_ad_new.php"
};
var patterns = {
    /*cinemas: /(http\:\/\/cinemacity\.bg\/program_ad_new\.php\?c_id=([0-9]?)*?)\"(?:\s+)?>(.*?)<\/a>/g,
    programURL: /<iframe.+src=\'(.*?)\'/,
    row: /<tr[\s\S]*?<\/tr>/g,
    col: /<td[\s\S]*?<\/td>/g,
    movieName: /(?:.*?)>(.*)<\//,
    movieURL: 'href="([^"]+?)"[^>]*?>\s*',
    movieImage: /<img\s*src="([^"]+?)"\s*(?:width=\"154\")\s*(?:height=\"225\")[^>]*?>/i,
    movieInfo: /<table[^>]*class="opistabela"*?>(.*?)<\/table>/i,
    movieTitle: /<h2[^>]+>([^<]+?)<\/h2>/i,
    innerText: /<[^>]+>([^<]+?)<\/[^>]+>/i,
    time: /(?:.*)>(.*?)<\/a/,*/
    innerText: /<\/?[^>]+>/gi,
    charset: /charset=(.*)/,
    clearName: /\s*?<\/?[^>]+>|\s*?(3D|2D|4DX|IMAX|\[[^\]]+\]|\([^\)]+\))(.*)$|\s*$/ig
};
var slug_pattern = {
    'щ' : 'sch',
    'ш' : 'sh',
    'ч' : 'ch',
    'ц' : 'c',
    'ю' : 'yu',
    'я' : 'ya',
    'ж' : 'zh',
    'а' : 'a',
    'б' : 'b',
    'в' : 'v',
    'г' : 'g',
    'д' : 'd',
    'е' : 'e',
    'з' : 'z',
    'й' : 'y',
    'и' : 'i',
    'к' : 'k',
    'л' : 'l',
    'м' : 'm',
    'н' : 'n',
    'о' : 'o',
    'п' : 'p',
    'р' : 'r',
    'с' : 's',
    'т' : 't',
    'у' : 'u',
    'ф' : 'f',
    'х' : 'h',
    'ы' : 'y',
    'ь' : 'a',
    'ъ' : 'a',
    ' ' : '_'
};
var cinemas = [];
var movies = [];
var programs = {};
var cinemasById = {};
var moviesBySlug = {};
var movie_urls = [];
var movie_urls_ByName = {};

/*if(process.env.VCAP_SERVICES){
    env = JSON.parse(process.env.VCAP_SERVICES);
    mongo = env['mongodb-1.8'][0]['credentials'];
}
else{
    mongo = {
        "hostname": "ds037368.mongolab.com",
        "port": 37368,
        "username": "root",
        "password": "Gal1234",
        "db": "cinemacity"
    };
}

function mongoURL(obj){
    if(obj.username && obj.password){
        return "mongodb://" + obj.username + ":" + obj.password + "@" + obj.hostname + ":" + obj.port + "/" + obj.db;
    }
    else{
        return "mongodb://" + obj.hostname + ":" + obj.port + "/" + obj.db;
    }
}*/



app.all('*', function(req, res, next){
    if (!req.get('Origin')) return next();
    res.set('Access-Control-Allow-Origin', '*');
    //res.set('Access-Control-Allow-Origin', 'http://cinemacity.hp-stuff.cu.cc');
    res.set('Access-Control-Allow-Methods', 'GET, POST');
    res.set('Access-Control-Allow-Headers', 'X-Requested-With, Content-Type');
    if ('OPTIONS' == req.method) return res.send(200);
    next();
});
app.get("/cinemas", function(req, res){
    if(cinemas.length == 0){
        requestUrl(urls.cinemas, function(window, charset){
            getCinemas(window, charset, function(){
                res.charset = "utf-8";
                res.set('Content-Type', 'application/json');
                res.send(JSON.stringify(cinemas));
            });
        });
    }else{
        res.charset = "utf-8";
        res.set('Content-Type', 'application/json');
        res.send(JSON.stringify(cinemas));
    }
});
app.get("/cinemas/:id/program/:date", function(req, res){
    var cinema = cinemasById[req.params.id];
    getProgram(cinema, req.params.date, function(data){
        res.charset = "utf-8";
        res.set('Content-Type', 'application/json');
        res.send(JSON.stringify({ cinema: cinema, date: req.params.date, movies: data }));
    });
});
app.get("/movie/:name", function(req, res){
    var movie = movie_urls_ByName[generateSlug(req.params.name)];

    getMovie(movie, function(movie){
        res.charset = "utf-8";
        res.set('Content-Type', 'application/json');
        res.send(JSON.stringify(movie));
    });
});
app.listen(process.env.VCAP_APP_PORT || 3000);
/*mongoclient.connect(mongoURL(mongo), function(err, db){
    //console.log(err, db);
    mongodb = db;

});*/


function requestUrl(url, callback){
    jsdom.env({
        url: url,
        encoding: "binary",
        done: function (errors, window) {
            var charset = window.document.querySelector("meta[http-equiv=Content-Type]");
            if(charset) charset = charset.content.match(patterns.charset)[1];
            callback(window, charset);
        }
    });
}

function getCinemas(window, charset, callback){
    var id, program_link_counter = 0, iconv, name,
        links = window.document.querySelectorAll("center font[color=orange] a");

    cinemas.length = 0;

    if(charset != "utf-8") iconv = new Iconv(charset, "utf8");

    Array.prototype.forEach.call(links, function(link){
        id = link.href.split("=")[1];

        if(iconv){
            name = iconv.convert(new Buffer(link.innerHTML, "binary")).toString();
        }
        else{
            name = new Buffer(link.innerHTML, "binary").toString();
        }
        cinemasById[id] = {
            id: id,
            url: link.href,
            name: name
        };
        programs[id] = {};
        getCinemaProgramURL(cinemasById[id], function(cinema){
//            c_cinemas.insert(cinema, function(err, docs){
//                console.log(err, docs);
//            });
            program_link_counter++;
            if(links.length == program_link_counter) callback();
        });
        cinemas.push(cinemasById[id]);

    });
}

function getCinemaProgramURL(cinema, callback){
    requestUrl(cinema.url, function(window, charset){
        var iframe = window.document.getElementsByTagName("iframe").item(0);
        if(iframe) cinema.programURL = iframe.src;
        callback(cinema);
    });
}

function getProgram(cinema, date, callback){
    var url, date = date || getNow();

    if(programs[cinema.id] && programs[cinema.id][date]){
        return callback(programs[cinema.id][date]);
    }

    url = cinema.programURL.split("&");
    url[1] = "c_date="+date;
    url = url.join("&");

    requestUrl(url, function(window, charset){
        callback(programs[cinema.id][date] = getMovies(window, charset));
    });
}

function getMovie(moviе, callback){
    requestUrl(moviе.url, function(window, charset){
        var iconv, movie = {}, info = [], cols,
            document = window.document,
            image = document.querySelector("img[width='154']"),
            desc = document.querySelector("p[align=justify]"),
            info_rows = document.getElementsByClassName("opistabela").item(0).getElementsByTagName("tr"),
            title = document.getElementsByTagName("h2").item(0);

        if(charset != "utf-8") iconv = new Iconv(charset, "utf8");
        console.log(info_rows.length);
        for(var i = 0; i < info_rows.length - 1; i++){
            cols = info_rows.item(i).getElementsByTagName("td");
            console.log(cols.item(0).innerHTML);
            if(iconv){
                info.push({
                    type: iconv.convert(new Buffer(cols.item(0).innerHTML, "binary")).toString(),
                    value: iconv.convert(new Buffer(cols.item(1).innerHTML, "binary")).toString()
                });
            }else{
                info.push({
                    type: new Buffer(cols.item(0).innerHTML, "binary").toString(),
                    value: new Buffer(cols.item(1).innerHTML, "binary").toString()
                });
            }
        }

        movie.info = info;
        movie.image = image.src;

        if(iconv){
            movie.description = iconv.convert(new Buffer(desc.innerHTML, "binary")).toString();
            movie.title = iconv.convert(new Buffer(title.innerHTML, "binary")).toString();
        }else{
            movie.description = new Buffer(desc.innerHTML, "binary").toString();
            movie.title = new Buffer(title.innerHTML, "binary").toString();
        }

        callback(movie);
    });
}

function getMovies(window, charset){
    var movies = [], cols, iconv, rows = window.document.getElementsByTagName("tr");

    if(charset != "utf-8") iconv = new Iconv(charset, "utf8");

    for(var i = 1; i < rows.length; i++){
        cols = rows[i].getElementsByTagName("td");
        var movie = {};
        if(iconv){
            movie.name = iconv.convert(new Buffer(cols[0].innerHTML, "binary")).toString();
        }else{
            movie.name = new Buffer(cols[0].innerHTML, "binary").toString();
        }

        movie.hours = [];
        for(var k = 1; k < cols.length; k++){
            if(cols[k].innerHTML) movie.hours.push(cols[k].innerHTML.replace(patterns.innerText, ""));
        }
        movies.push(movie);
    }

    return movies;
}

function generateSlug(text){
    text = text.replace(patterns.clearName, "").toLowerCase();
    return text.replace(/[^a-z0-9]/ig, function(key){ return slug_pattern[key] || ""; });
}

function getNow(){
    var d = new Date();
    return [d.getFullYear(), ("0"+(d.getMonth()+1)).slice(-2), ("0"+d.getDate()).slice(-2)].join("-");
}

function getMoviesURL(callback){
    var all = 2, counter = 0;
    requestUrl("http://cinemacity.bg/film_01.php", function(window, charset){
        addMoviesURL(window, charset);
        counter++;
        if(counter == all) callback();
    });
    requestUrl("http://cinemacity.bg/cs_04.php", function(window, charset){
        addMoviesURL(window, charset);
        counter++;
        if(counter == all) callback();
    });
}

function addMoviesURL(window, charset){
    var name, iconv, slug, links = window.document.querySelectorAll("span h3 a");

    if(charset != "utf-8") iconv = new Iconv(charset, "utf8");

    Array.prototype.forEach.call(links, function(link){
        name = link.innerHTML.replace(patterns.clearName, "");

        if(iconv){
            name = iconv.convert(new Buffer(name, "binary")).toString();
        }else{
            name = new Buffer(name, "binary").toString();
        }
        slug = generateSlug(name);

        if(movie_urls_ByName[slug] && movie_urls_ByName[slug].url.split("?")[0] == link.href.split("?")[0]) return;

        movie_urls_ByName[slug] = {
            name: name,
            url: link.href
        };

        movie_urls.push(movie_urls_ByName[slug]);
    });
}

getMoviesURL(function(){
    console.log(JSON.stringify(movie_urls_ByName));
});